package com.thingsgrid.application.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.google.gson.Gson;
import com.thingsgrid.application.entity.AppApi;
import com.thingsgrid.application.service.IAppApiService;
import com.thingsgrid.basicInterface.entity.BasicInterface;
import com.thingsgrid.basicInterface.feign.BasicInterfaceClient;
import com.thingsgrid.basicInterface.vo.BasicInterfaceVo;
import com.thingsgrid.basicInterface.vo.TypeTree;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.thingsgrid.application.entity.Application;
import com.thingsgrid.application.vo.ApplicationVO;
import com.thingsgrid.application.wrapper.ApplicationWrapper;
import com.thingsgrid.application.service.IApplicationService;
import org.springblade.core.boot.ctrl.BladeController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 应用表 控制器
 *
 * @author BladeX
 * @since 2019-08-13
 */
@RestController
@AllArgsConstructor
@RequestMapping("/test/application")
@Api(value = "应用", tags = "应用微服务")
public class ApplicationController extends BladeController {

	private Map<Long,HashSet<Long>> appApiMap = new HashMap<>();

	@Value("${server.port}")
	private String  port;
	@Value("${uploadPath}")
	private String  uploadPath;

	@Autowired
	private IApplicationService applicationService;
	@Autowired
	private BasicInterfaceClient basicInterfaceClient;
	@Autowired
	private IAppApiService appApiService;




	/**
	 * 新增或修改 应用表
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "新增或修改", notes = "传入application")
	public R submit(@Valid @RequestBody Application application) {
		if(null == application.getId()){
			Application one = applicationService.getOne(new LambdaQueryWrapper<Application>()
				.eq(Application::getAppName, application.getAppName())
				.eq(Application::getOwnerId, application.getOwnerId()));
			if(one != null){
				throw  new ApiException("应用名称已存在");
			}
		}

		// TODO  设计其他信息 所属人ID-姓名-AK-CK
		application.setVersion("1.0");
		return R.status(applicationService.saveOrUpdate(application));
	}

	/**
	* 详情
	*/
	@GetMapping("/detail")
    @ApiOperationSupport(order = 6)
	@ApiOperation(value = "详情", notes = "传入application")
	public R<HashMap<String,Object>> detail(Application application) {
		HashMap<String, Object> hashtable = new HashMap<>();
		Application detail = applicationService.getById(application.getId());
		ApplicationVO applicationVO = ApplicationWrapper.build().entityVO(detail);
		hashtable.put("tab1",applicationVO);
		// 已经申请的接口
		List<AppApi> appApis = appApiService.list(new LambdaQueryWrapper<AppApi>()
			.eq(AppApi::getAppId, application.getId()));
		Collection<Long> apiIds = appApis.stream().map(e -> e.getApiId()).collect(Collectors.toList());
		List<BasicInterfaceVo> applicationApi = new ArrayList<BasicInterfaceVo>();
		if(!apiIds.isEmpty()) {
            applicationApi = basicInterfaceClient.getApplicationApi(apiIds);
        }
		hashtable.put("tab2",applicationApi);
		appApiMap.put(application.getId(),new HashSet<>(apiIds));

		String apiTree = basicInterfaceClient.getAPITree(apiIds);
		Gson gson = new Gson();
		TypeTree [] typeTrees = gson.fromJson(apiTree,  TypeTree[].class);
		List<TypeTree> typeTrees1 = Arrays.asList(typeTrees);
		hashtable.put("tab3",typeTrees1);
		String apiTreeByPackage = basicInterfaceClient.getAPITreeByPackage(apiIds);
		hashtable.put("tab4",Arrays.asList(gson.fromJson(apiTreeByPackage,  TypeTree[].class)));
		return R.data(hashtable);
	}


	@GetMapping("/appTypeApi")
	public R getAppUnAPi(Long id,Long appId){
		List<BasicInterfaceVo> typeInterface = basicInterfaceClient.getTypeInterface(id);
		Collection<Long> longs = appApiMap.get(appId);
		if(!longs.isEmpty()){
			List<BasicInterface> collect = typeInterface.stream().filter(e -> !longs.contains(e.getApiId())).collect(Collectors.toList());
			return R.data(collect);
		}
		return  R.data(typeInterface);
	}


	/**
	* 分页 应用表
	*/
	@GetMapping("/list")
    @ApiOperationSupport(order = 2)
	@ApiOperation(value = "查看应用列表", notes = "传入application")
	public R<IPage<ApplicationVO>> list(@RequestParam Map<String, Object> application, Query query) {
		/** 注意构造条件 传入一个Map和JavaBean类*/
		IPage<Application> pages = applicationService.page(Condition.getPage(query), Condition.getQueryWrapper(application,Application.class));
		return R.data(ApplicationWrapper.build().pageVO(pages));
	}



	/**
	* 删除 应用表
	*/
	@PostMapping("/remove")
    @ApiOperationSupport(order = 3)
	@ApiOperation(value = "删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(applicationService.removeByIds(Func.toLongList(ids)));
	}


	/**
	 * 应用绑定接口
	 * @param id
	 * @param apiIds
	 * @return
	 */
	@PostMapping("/application/api")
	public R appAddApi(@RequestParam(value = "id") Long id ,@RequestParam(value = "apiIds") String apiIds){
		List<Long> ids = Func.toLongList(apiIds);
		List<AppApi> AppApis = ids.stream().map(apiId -> new AppApi().setApiId(apiId).setAppId(id)).collect(Collectors.toList());
		boolean b = appApiService.saveBatch(AppApis);
		// todo  更新Map
		if(b){
			HashSet<Long> longs = appApiMap.get(id);
			if(null != longs && !longs.isEmpty()) {
                ids.addAll(longs);
            }
			appApiMap.put(id,new HashSet<>(ids));
		}
		return R.status(b);
	}


	@RequestMapping("fileUpload")
	public String uploadFile1(MultipartFile[]  file , HttpServletRequest request) throws UnknownHostException {
		ArrayList<String> nameStr = new ArrayList<>();
		File dirFile = new File(uploadPath);
		if(!dirFile.exists()){
			dirFile.mkdirs();
		}
		for(MultipartFile file1 :file){
			String nameRan = RandomStringUtils.randomAlphanumeric(10);
			String newFileName = nameRan + file1.getOriginalFilename().substring(file1.getOriginalFilename().lastIndexOf("."));

			File newFile = new File(uploadPath + "/" + newFileName);
			InetAddress localHost = InetAddress.getLocalHost();
			String ip = localHost.getHostAddress();
			String picAddress = "http://"+ip+":"+port+"/show?fileName="+newFileName;
			nameStr.add(picAddress);
			try {
				file1.transferTo(newFile);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		String join = StringUtils.join(nameStr, ",");
		return join;
	}

	private final ResourceLoader resourceLoader;

	@Autowired
	public ApplicationController(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}


	@GetMapping("/show")
	public ResponseEntity showImage(String fileName) {
		try { // 由于是读取本机的文件，file是一定要加上的， path是在application配置文件中的路径
			// linux -----
			return ResponseEntity.ok(resourceLoader.getResource("file:" + uploadPath + "/"+fileName));
			//return ResponseEntity.ok(resourceLoader.getResource("file:" + "D:/song1234" + fileName));
		} catch (Exception e) {
			return ResponseEntity.notFound().build();
		}
	}



}
